<?php

namespace App\Exceptions;

use Illuminate\Auth\AuthenticationException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Http\Exceptions\ThrottleRequestsException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Routing\Exceptions\InvalidSignatureException;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Throwable;

class Handler extends ExceptionHandler
{
    protected $dontFlash = [
        'current_password',
        'password',
        'password_confirmation',
    ];

    public function register(): void
    {
    }

    protected function unauthenticated(
        $request,
        AuthenticationException $exception
    ): JsonResponse|Response|RedirectResponse {
        return $this->shouldReturnJson($request, $exception)
            ? response()->json([
                'code' => 401,
                'message' => $exception->getMessage() ?: __('messages.not_login'),
            ])
            : redirect()->guest($exception->redirectTo() ?? route('login'));
    }

    protected function prepareJsonResponse($request, Throwable $e): JsonResponse
    {
        $json = match (true) {
            $e instanceof ThrottleRequestsException => [
                'code' => $e->getStatusCode(),
                'message' => $e->getMessage() ?: __('messages.to_many_request'),
            ],
            $e instanceof InvalidSignatureException => [
                'code' => $e->getStatusCode(),
                'message' => $e->getMessage() ?: __('messages.invalid_signature'),
            ],
            $e instanceof NotFoundHttpException => [
                'code' => $e->getStatusCode(),
                'message' => $e->getMessage() ?: __('messages.api_notfound'),
            ],
            $e instanceof MethodNotAllowedHttpException => [
                'code' => $e->getStatusCode(),
                'message' => $e->getMessage() ?: __('messages.method_not_allowed'),
            ],
            default => [
                'code' => $e->getCode(),
                'message' => $e->getMessage(),
            ]
        };
        if (Str::startsWith($request->getRequestUri(), '/admin')) {
            return response()->json([
                'status' => false,
                'data' => [
                    'message' => $json['message'],
                    'type' => 'error',
                ],
            ]);
        }
        if (config('app.debug')) {
            $json['file'] = $e->getFile();
            $json['line'] = $e->getLine();
        }

        return response()->json(
            $json
        );
    }

    protected function invalidJson($request, ValidationException $exception): JsonResponse
    {
        return response()->json([
            'code' => 422,
            'message' => $exception->getMessage(),
        ]);
    }
}
